/*
  author Sylvain Bertrand <sylvain.bertrand@gmail.com>
  Protected by linux GNU GPLv2
  Copyright 2012-2014
*/
#include <linux/pci.h>
#include <linux/firmware.h>
#include <linux/cdev.h>

#include <alga/rng_mng.h>
#include <alga/timing.h>
#include <uapi/alga/pixel_fmts.h>
#include <uapi/alga/amd/dce6/dce6.h>

#include "mc.h"
#include "rlc.h"
#include "ih.h"
#include "fence.h"
#include "ring.h"
#include "dmas.h"
#include "ba.h"
#include "cps.h"
#include "gpu.h"
#include "drv.h"

#include "regs.h"

long ucode_load(struct pci_dev *dev, const struct firmware **fw,
						const char *fw_str, u32 fw_dws)
{
	struct dev_drv_data *dd;
	const char *chip_name;
	u32 req_sz;
	char fw_name[30];
	long r;

	chip_name = NULL;

	dd = pci_get_drvdata(dev);

	switch (dd->family) {
	case TAHITI:
		chip_name = "TAHITI";
		break;
	case PITCAIRN:
		chip_name = "PITCAIRN";
		break;
	case VERDE:
		chip_name = "VERDE";
		break;
	case OLAND:
		chip_name = "OLAND";
		break;
	}

	req_sz = fw_dws * 4;

	dev_info(&dev->dev, "loading %s_%s ucode\n", chip_name, fw_str);

	*fw = NULL;

	snprintf(fw_name, sizeof(fw_name), "radeon/%s_%s.bin", chip_name,
									fw_str);
	r = request_firmware(fw, fw_name, &dev->dev);
	if (r) {
		dev_err(&dev->dev, "unable to load %s ucode:%s\n", fw_str,
								fw_name);
		return -SI_ERR;
	}
	if ((*fw)->size != req_sz) {
		dev_err(&dev->dev, "bogus length %zu in %s firmware \"%s\"\n",
						(*fw)->size, fw_str, fw_name);
		release_firmware(*fw);
		return -SI_ERR;
	}
	return 0;
}
